import datetime
import time

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By

from craft import craft_only_items
from libs import config
from libs.action import WebDriverAction
from libs.cache import Cache
from libs.game import Game
from libs.image import ImageTool
from libs.log import Log
from libs.movement import Movement
from libs.trade_helper import TradeHelper, TaskItem, FailReason
from libs.window import AdsWindow
from libs.task_helper import TaskHelper

making_items = craft_only_items


def prepare_make_item():
    task_need_items = {}
    for index in trade_helper.tasks:
        task: TaskItem = trade_helper.tasks.get(index)
        if task.name in making_items:
            task_need_items[task.name] = task_need_items.get(task.name, 0) + task.qty

    chest_out = []
    for index in making_chest_items:
        chest_item = making_chest_items.get(index)
        if chest_item.get('name') == 'Tato Hash':
            chest_out.append(index)
    for need_name in task_need_items:
        need_qty = task_need_items.get(need_name)
        if game.get_backpack_qty(need_name) < need_qty and get_making_chest_qty(need_name) > 0:
            for index in making_chest_items:
                chest_item = making_chest_items.get(index)
                if chest_item.get('name') == need_name:
                    chest_out.append(index)

    if len(chest_out) > 0:
        open_making_chest()  # 打开箱子
        time.sleep(1)
        cell_items = driver.find_elements(By.CLASS_NAME, 'InventoryWindow_inventoryItem__z7YhV')
        for index in chest_out:
            cell_elem = cell_items[index]
            if cell_elem:
                ac.move_to_element(cell_elem).perform()
                ac.context_click().perform()
                time.sleep(0.5)
                ac.context_click().perform()
                making_chest_items[index] = {}  # 更新箱子库存
        action.escape()
        action.escape()
        game.get_backpack()


def get_making_chest_qty(item_name):
    qty = 0
    for item in making_chest_items.values():
        if item.get('name') == item_name:
            qty += item.get('qty', 0)
    return qty


def open_making_chest():
    hmr_image = 'house_manager_root.png'
    # 取物品
    hmr_loc = image_tool.find_target(hmr_image)
    hmr_x, hmr_y = hmr_loc
    action.click_by_offset(hmr_x + 40, hmr_y + 100)

def get_sell_items():
    return ['Honey', 'Wax', 'Glass Bottle', 'Silk Slug']


if __name__ == "__main__":
    parser = TaskHelper.default_args_parser('Trade')
    args = parser.parse_args()
    task_helper = TaskHelper.from_args(args)

    user_id = args.user_id
    log = Log(user_id)
    # 启动窗口
    driver = AdsWindow(user_id).open(False)
    ac = ActionChains(driver)
    action = WebDriverAction(driver, user_id=user_id)
    movement = Movement(driver)
    image_tool = ImageTool(driver)
    game = Game(driver, user_id)
    trade_helper = TradeHelper(driver, user_id)
    account = config.get_account(user_id)
    cache = Cache()
    log.info(f"trade start")

    # 进入游戏
    game.enter_game(user_id)

    snapshot = game.snapshot(user_id, 'after_collect_mail')
    skills = snapshot.get('skills')
    items = config.get_items()
    total_deliver = 0
    one_task_rounds = 0
    no_deliver_rounds = 0
    fail_times = 0

    action.goto_task_board()

    open_making_chest()
    making_chest_items = game.chest_scan()
    action.escape()

    for task_round in range(30):
        try:
            action.escape()
            action.escape()
            game.enter_game(user_id)
            # 收邮件
            game.collect_mail()
            game.snapshot(user_id, 'loop start', include_skills=False)
            # 1. 查看任务
            action.goto_task_board()
            port_count = trade_helper.check_tasks()
            action.escape()

            # 2. 商店购买
            backpack = game.get_backpack()
            coin_before = game.get_coin()
            p_before = game.get_p()
            prepare_make_item()

            trade_helper.goto_buy_position()
            trade_helper.game.backpack = backpack
            trade_helper.buy()
            action.escape()

            # 3. 交任务
            action.goto_task_board()
            deliver_count = trade_helper.deliver()
            time.sleep(1)
            coin_spent = coin_before - game.get_coin()
            p_received = game.get_p() - p_before
            total_deliver += deliver_count
            log.info(f"round {task_round}, deliver {deliver_count}/{port_count}, left coin {game.get_coin()}")

            start = datetime.datetime.now()
            if deliver_count == 0:
                if no_deliver_rounds > 0:
                    log.info(
                        f"trade finish, loop={task_round}, deliver_count={total_deliver}, no_deliver_rounds={no_deliver_rounds}")
                    break
                else:
                    no_deliver_rounds += 1
            else:
                no_deliver_rounds = 0

            if deliver_count == 1:
                limit = trade_helper.trade_config.get('one_task_rounds', 1)
                one_task_rounds += 1
                if one_task_rounds >= limit:
                    log.info(
                        f"trade finish, loop={task_round}, deliver_count={total_deliver}, one_task_rounds={one_task_rounds}")
                    break
            else:
                one_task_rounds = 0

            time_left = 120 - (datetime.datetime.now() - start).seconds
            if time_left > 0:
                log.debug(f'wait {time_left} seconds')
                time.sleep(time_left)
        except Exception as e:
            fail_times += 1
            log.info('error occurred')
            print(e)
            if fail_times > 3:
                break
            else:
                continue

    time.sleep(5)

    action.goto_task_board()
    # 存物品
    hmr_loc = image_tool.find_target('house_manager_root.png')
    hmr_x, hmr_y = hmr_loc
    game.chest_in(hmr_x + 35, hmr_y + 110, making_items.keys())

    try:
        # 去睡觉
        movement.keep_move_right(3.5)
        bed_loc = image_tool.find_target('bed.png')
        if bed_loc:
            bed_x, bed_y = bed_loc
            action.move_by_offset(bed_x - 80, bed_y - 40)
            for _ in range(4):
                target = action.find_element(By.CLASS_NAME, 'LookAtBubble_lookAtBubble___pd4a', 'LookAtBubble', 1)
                if target is None:
                    time.sleep(0.5)
                    continue
                elif target.text == 'Sleep to Gain Energy':
                    log.info('sleep')
                    action.click()
                    time.sleep(60)
                    break
                else:
                    continue

        action.escape()
        action.escape()
        time.sleep(10)
        game.snapshot(user_id, 'after_trade')
    except Exception as e:
        print(e)
        pass

    if fail_times > 3:
        task_helper.task_fail()
        task_helper.trade(retry=True)
    else:
        # 24小时后再次执行
        task_helper.task_success()
        hour = datetime.datetime.now().hour
        minute = datetime.datetime.now().minute
        run_time = datetime.datetime.now().replace(hour=8, minute=minute)
        if hour >= 8:
            run_time = run_time + datetime.timedelta(days=1)
        delay_seconds = (run_time - datetime.datetime.now()).total_seconds()
        task_helper.trade(delay_seconds=delay_seconds)
        task_helper.add_task('craft.py', delay_seconds=0)

        if account.get('wine', True):
            task_helper.wine()
